#!/bin/bash
# vars used:
# util/get-config: GS_BUCKET, GCE_ZONE, GCE_PROJECT, RUN_INTERNAL

XFSTESTS_FLAVOR=gce
t=$(echo ${XFSTESTS_FLAVOR}_xfstests_dir | tr "[:lower:]" "[:upper:]")
eval DIR="\$$t"
if test -z "$DIR"
then
    DIR="$(dirname "$(dirname "$0")")"
fi
if test ! -f "$DIR/util/get-config"
then
    echo "$(basename "$0"): couldn't find $DIR/util/get-config"
    exit 1
fi

. "$DIR/util/get-config"
. "$DIR/util/arch-funcs"

while (( $# >= 1 )); do
    case $1 in
	--image-project) shift
	    GCE_IMAGE_PROJECT="$1"
	    ;;
	--image-family) shift
	    ROOT_FS="$1"
	    IMAGE_FLAG="--image-family"
	    EXPLICIT_ROOT_FS=yes
	    ;;
	-I) shift
	    ROOT_FS="$1"
	    IMAGE_FLAG="--image"
	    EXPLICIT_ROOT_FS=yes
	    ;;
	--arch) shift
	    ARCH="$1"
	    ;;
	*)
	    echo "Invalid option \"$1\""
	    shift
	    ;;
    esac
    shift
done

set_canonicalized_arch "$ARCH"

if test -z "$GCE_IMAGE_PROJECT" ; then
    GCE_IMAGE_PROJECT="xfstests-cloud"
fi

if test -z "$EXPLICIT_ROOT_FS" ; then
    ROOT_FS="xfstests-$ARCH"
    IMAGE_FLAG="--image-family"
fi

INSTANCE="xfstests-kcs"

if test -f "$DIR/.kcs_cookie_$GCE_PROJECT"; then
    echo "Removing old cookies..."
    rm -f "$DIR/.kcs_cookie_$GCE_PROJECT"
fi

NO_ACTION=

DESCRIBE=$(run_gcloud_always compute instances describe \
    --zone $GCE_ZONE $INSTANCE 2> /dev/null)
if test -n "$DESCRIBE"
then
    KCS_ARCH=$(echo "$DESCRIBE" | sed -rn 's/.*architecture: (.*)/\1/p' )

    if test "$KCS_ARCH" != "$GCE_ARCH"; then
	echo "KCS server is already running on $KCS_ARCH instance but $ARCH requested."
	echo "Please delete the KCS instance and try again."
	exit 1
    fi

    if [ -f $DIR/.kcs_instance_$GCE_PROJECT ]
    then
	echo "The KCS instance already exists!"
	exit 1
    else
	echo "The KCS server instance already exists, but .kcs_instance_$GCE_PROJECT is not present."
	echo "Re-creating .kcs_instance_$GCE_PROJECT..."
	NO_ACTION=": "
    fi
fi
if ! gsutil -q stat "gs://$GS_BUCKET/ltm-pass" &> /dev/null
then
    echo "There is no password in your GS bucket $GS_BUCKET"
    echo "for the build server to authenticate requests with."
    echo "You can generate a password by running gce-xfstests setup, or by"
    echo "uploading a password of your choice (a string) to your bucket at"
    echo "gs://$GS_BUCKET/ltm-pass"
    echo "The password will automatically be used by the kcs command line"
    echo "option."
    exit 1
fi

if test -z "$GCE_KCS_MACHTYPE" ; then
    case "$ARCH" in
	amd64)
	    GCE_KCS_MACHTYPE="n2-standard-4"
	    ;;
	arm64)
	    GCE_KCS_MACHTYPE="t2a-standard-4"
	    ;;
    esac
fi

GS_RW=https://www.googleapis.com/auth/devstorage.read_write
LOG_WR=https://www.googleapis.com/auth/logging.write
COMPUTE_RW=https://www.googleapis.com/auth/compute
SCOPES="$GS_RW,$COMPUTE_RW,$LOG_WR"

PREEMPTIBLE="--maintenance-policy MIGRATE"

ARG="gs_bucket=$GS_BUCKET serial-port-enable=$GCE_SERIAL_PORT_ACCESS"
ARG="$ARG gce_xfs_kcs=YES"
if test -n "$TZ" ; then
    ARG="$ARG fstesttz=$TZ"
fi

if ! gsutil -q stat gs://$GS_BUCKET/gce-xfstests-cert.pem
then
    echo "You do not have a generated SSL certificate in your GCS bucket."
    echo "It is not possible to communicate with the build server."
    echo "Please run gce-xfstests setup and then restart the build server."
    exit 1
fi

if ! gsutil -q stat gs://$GS_BUCKET/gce_xfstests.config
then
    echo "You must run gce-xfstests setup to upload a .config file"
    echo "to your GCS bucket."
    exit 1
fi

echo "Launching build server..."
touch $DIR/.kcs_instance_$GCE_PROJECT
LAUNCH_KCS_EXIT_STATUS=1
trap 'if [ $LAUNCH_KCS_EXIT_STATUS != 0 ]; then rm $DIR/.kcs_instance_$GCE_PROJECT; fi' EXIT

run_gcloud compute \
    instances create "$INSTANCE" --zone "$GCE_ZONE" \
    --machine-type "$GCE_KCS_MACHTYPE" --network "$GCE_NETWORK" \
    --boot-disk-size 50GB \
    $PREEMPTIBLE \
    $SERVICE_ACCOUNT_OPT_LTM \
    --scopes "$SCOPES" \
    --metadata "^ ^$ARG" \
    --tags http-server,https-server \
    --image-project "${GCE_IMAGE_PROJECT}" \
    "$IMAGE_FLAG" "$ROOT_FS"

if [ $? != 0 ]
then
    echo "Could not start the build server."
    exit 1
fi

if [ ! -f $DIR/.gce_xfstests_cert_$GCE_PROJECT.pem ]
then
    gsutil cat gs://$GS_BUCKET/gce-xfstests-cert.pem > $DIR/.gce_xfstests_cert_$GCE_PROJECT.pem
fi

echo "GCE_KCS_SERVER_CERT=$DIR/.gce_xfstests_cert_$GCE_PROJECT.pem" > $DIR/.kcs_instance_$GCE_PROJECT
echo "GCE_KCS_NAME=$INSTANCE" >> $DIR/.kcs_instance_$GCE_PROJECT
echo -n "GCE_KCS_EXT_IP=" >> $DIR/.kcs_instance_$GCE_PROJECT
echo -n "Waiting for VM to boot to grab external IP..."

function wait_for_command() {
    local my_cmd=$1
    local cnt=0
    until $my_cmd &> /dev/null
    do
	(( cnt += 1 ))
	if (( cnt >= 5 )); then
	    echo -n "."
	    cnt=0
	fi
	sleep 1
    done
}
wait_for_command "run_gcloud compute instances describe \
    --zone $GCE_ZONE $INSTANCE"
echo " Done!"

NO_ACTION=
run_gcloud compute instances describe "$INSTANCE" --zone "$GCE_ZONE" \
    --format="get(networkInterfaces[0].accessConfigs[0].natIP)" >> $DIR/.kcs_instance_$GCE_PROJECT

# use internal ip if this machine is in the same GCE project
if test -n "$RUN_INTERNAL"; then
    echo "Runs on same GCE project so grab internal IP"
    echo -n "GCE_KCS_INT_IP=" >> $DIR/.kcs_instance_$GCE_PROJECT

    run_gcloud compute instances describe "$INSTANCE" --zone "$GCE_ZONE" \
        --format="get(networkInterfaces[0].networkIP)" >> $DIR/.kcs_instance_$GCE_PROJECT
fi

echo -n "Fetching password..."
wait_for_command "gsutil -q stat gs://$GS_BUCKET/ltm-pass"
echo -n "GCE_KCS_PWD=" >> $DIR/.kcs_instance_$GCE_PROJECT
gsutil cat gs://$GS_BUCKET/ltm-pass >> $DIR/.kcs_instance_$GCE_PROJECT
LAUNCH_KCS_EXIT_STATUS=0
echo "Done!"
